package roborally.program.conditions;

import be.kuleuven.cs.som.annotate.*;
import roborally.model.EnergyAmount;
import roborally.model.Robot;

/**
 * A class for dealing with energy-at-least-conditions: (energy-at-least ....).  
 * 
 * @invar	The energy amount associated with each energy-at-least-condition must
 * 			be a valid energy amount.
 * 			| canHaveAsEnergy(getEnergy())
 * 
 * @version	1.0
 * @author  Pieter Robberechts	(1e Bach Informatica)
 * @author	Jeroen Sanders		(1e Bach Informatica)
 *
 */
public class EnergyAtLeast extends Condition {

	/**
	 * Initialize this new energy-at-least-condition with a line number and energy amount.
	 * 
	 * @param 	energy
	 * 			The amount of energy associated with this condition (in Ws).
	 * @pre		The given energy amount must be a valid energy amount for this condition.
	 * 			| canHaveAsEnergy(energy)
	 * @post	The given energy amount is set as the energy amount for this condition.
	 * 			| new.getEnergy() == energy
	 */
	public EnergyAtLeast(int lineNb, EnergyAmount energy) {
		super(lineNb);
		assert(canHaveAsEnergy(energy));
		this.energy = energy;
	}
	
	/**
	 * Variable registering the amount of energy associated with this condition.
	 */
	private final EnergyAmount energy;
	
	/**
	 * Return the amount of energy associated with this condition.
	 */
	@Basic @Raw @Immutable
	public EnergyAmount getEnergy() {
		return energy;
	}
	
	/**
	 * Check whether the given energy amount is a valid amount 
	 * for an energy-at-least-condition.
	 * 
	 * @param 	energy
	 * 			The energy amount to check for whether it is a valid one.
	 * @return	Return true if and only if and only if the given energy amount is effective;
	 * 			else return false.
	 * 			| result == ( energy != null )
	 */
	@Raw
	public boolean canHaveAsEnergy(EnergyAmount energy) {
		return ( energy != null );
	}

	/**
	 * Evaluate this condition for a given robot.
	 * 
	 * @return	Return true if and only if the energy of the given robot isn't less
	 * 			than the energy amount associated with this energy-at-least-condition;
	 * 			else return false.
	 * 			| result == ( super.evaluate(robot) && 
	 * 			|				! robot.getEnergy().lessThan(getEnergy()) )
	 */
	@Override
	public boolean evaluate(Robot robot) {
		return ( super.evaluate(robot) && ! robot.getEnergy().lessThan(getEnergy()) );
	}
	
	/**
	 * Return a textual representation of this energy-at-least-condition,
	 * formatted in accordance with its position in the program.
	 * 
	 * @return	The result is a pretty formatted string of this energy-at-least-condition,
	 * 			taking in account his relative position in the program.
	 * 			| result == getIndentation(indentationLevel) + 
	 * 			|			"(energy-at-least: " + getEnergy().getAmountInUnits() + ")"
	 */
	@Override
	public String prettyFormat(int indentationLevel) {
		return getIndentation(indentationLevel) + 
				"(energy-at-least: " + getEnergy().getAmountInUnits() + ")";
	}

}
